package com.sso.core.filter;

import com.sso.core.conf.SSOConf;
import com.sso.core.login.SsoWebLoginHelper;
import com.sso.core.path.impl.AntPathMatcher;
import com.sso.core.user.SsoUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * app and web mixture sso filter
 *
 */
public class SsoFilter extends HttpServlet implements Filter {
    private static Logger logger = LoggerFactory.getLogger(SsoFilter.class);

    private static final AntPathMatcher antPathMatcher = new AntPathMatcher();

    private String ssoServer;
    private String logoutPath;
    private String excludedPaths;
    private String redirectUrl;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        ssoServer = filterConfig.getInitParameter(SSOConf.SSO_SERVER);
        ssoServer = ssoServer.trim();
        if (ssoServer.endsWith("/")) {
            ssoServer = ssoServer.substring(0, ssoServer.length() - 1);
        }

        logoutPath = filterConfig.getInitParameter(SSOConf.SSO_LOGOUT_PATH);
        excludedPaths = filterConfig.getInitParameter(SSOConf.SSO_EXCLUDED_PATHS);
        redirectUrl = filterConfig.getInitParameter(SSOConf.REDIRECT_URL);

        logger.info("-----------MySsoWebFilter init param ssoServer -> {}" , ssoServer);
        logger.info("-----------MySsoWebFilter init param logoutPath -> {}" , logoutPath);
        logger.info("-----------MySsoWebFilter init param excludedPaths -> {}" , excludedPaths);
        logger.info("-----------MySsoWebFilter init param redirectUrl -> {}" , redirectUrl);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "*");
        res.addHeader("Access-Control-Allow-Headers", "*");

        // make url
        String servletPath = req.getServletPath();

        // excluded path check
        if (excludedPaths!=null && excludedPaths.trim().length()>0) {
            for (String excludedPath:excludedPaths.split(",")) {
                String uriPattern = excludedPath.trim();

                // 支持ANT表达式
                if (antPathMatcher.match(uriPattern, servletPath)) {
                    // excluded path, allow
                    chain.doFilter(request, response);
                    return;
                }

            }
        }

        // logout path check
        if (logoutPath!=null&& logoutPath.trim().length()>0 && logoutPath.equals(servletPath)) {
            // remove cookie
            SsoWebLoginHelper.removeSessionIdByCookie(req, res);
            // redirect logout
            String logoutPageUrl = ssoServer.concat(SSOConf.SSO_LOGOUT);
            res.sendRedirect(logoutPageUrl);
            return;
        }

        SsoUser ssoUser = SsoWebLoginHelper.loginCheckAll(req, res);
        if (ssoUser == null) {

            String header = req.getHeader("content-type");
            boolean isJson=  header!=null && header.contains("json");
            if (isJson) {
                // json msg
                res.setStatus(HttpServletResponse.SC_OK);
                res.setContentType("application/json;charset=UTF-8");
                res.getWriter().println("{\"code\":" + SSOConf.SSO_LOGIN_FAIL_RESULT.getCode() + ", \"msg\":\"" + SSOConf.SSO_LOGIN_FAIL_RESULT.getMsg() + "\",\"ssoUrl\":\"" + ssoServer + SSOConf.SSO_LOGIN + "?" + SSOConf.REDIRECT_URL + "=" + redirectUrl + "\"}");
                return;
            } else {

                String link = req.getRequestURL().toString();
                String loginPageUrl = ssoServer.concat(SSOConf.SSO_LOGIN) + "?" + SSOConf.REDIRECT_URL + "=" + link;
                res.sendRedirect(loginPageUrl);
                return;
            }

        }

        request.setAttribute(SSOConf.SSO_USER, ssoUser);
        chain.doFilter(request, response);
        return;
    }

}
